package matchmaker;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 
 * @author Seabook
 * Awesome OO thoughs to solve such issue.
 *
 */
public class MatchMaker {

	public static void main(String[] args) {
		String[] members = new String[] {

		"BETTY F M A A C C", "TOM M F A D C A", "SUE F M D D D D",
				"ELLEN F M A A C A", "JOE M F A A C A", "ED M F A D D A",
				"SALLY F M C D A B", "MARGE F M A A C C" };

		MatchMaker maker = new MatchMaker();
		print(maker.getBestMatches(members, "BETTY", 2));
		print(maker.getBestMatches(members, "JOE", 1));
		print(maker.getBestMatches(members, "MARGE", 4));
	}

	private static void print(String[] bestMatches) {
		if (bestMatches == null || bestMatches.length == 0) {
			System.out.println("{ }");
		}

		for (String name : bestMatches) {
			System.out.print(name + ", ");
		}
		System.out.println();
	}

	public String[] getBestMatches(String[] members, String currentUser, int sf) {
		List<MemberInfo> membersList = generateMembers(members);

		MemberInfo requestMemberInfo = null;
		for (MemberInfo member : membersList) {
			if (member.name.equals(currentUser)) {
				requestMemberInfo = member;
				break;
			}
		}
		List<String> answers = requestMemberInfo.answers;
		String requesGender = requestMemberInfo.requestGender;
		membersList.remove(requestMemberInfo);

		List<MemberInfo> copymembersList = new ArrayList<MemberInfo>();
		for (MemberInfo member : membersList) {
			if (member.myGender.equals(requesGender)) {
				copymembersList.add(member);
			}
		}

		List<MemberInfo> matchedList = new ArrayList<MemberInfo>();
		for (MemberInfo member : copymembersList) {
			List<String> targetAnswers = member.answers;
			int ansMatchedNo = compareAnswer(answers, targetAnswers);
			if (ansMatchedNo >= sf) {
				member.matchedNumber = ansMatchedNo;
				matchedList.add(member);
			}
		}

		Collections.sort(matchedList);

		List<String> matchedNames = new ArrayList<String>();
		for (MemberInfo member : matchedList) {
			matchedNames.add(member.name);
		}

		return matchedNames.toArray(new String[] {});
	}

	private int compareAnswer(List<String> answers, List<String> targetAnswers) {
		int count = 0;
		for (int i = 0; i < answers.size(); i++) {
			String sourceAnswer = answers.get(i);
			String targetAnswer = targetAnswers.get(i);
			if (sourceAnswer.equals(targetAnswer)) {
				count++;
			}
		}

		return count;

	}

	private List<MemberInfo> generateMembers(String[] membersArr) {
		List<MemberInfo> members = new ArrayList<MemberInfo>();
		for (String member : membersArr) {
			String[] memberInfo = member.split(" ");
			String name = memberInfo[0];
			String myGender = memberInfo[1];
			String requestGender = memberInfo[2];
			List<String> answers = new ArrayList<String>(Arrays.asList(Arrays
					.copyOfRange(memberInfo, 3, memberInfo.length - 1)));
			MemberInfo info = new MemberInfo(name, myGender, requestGender,
					answers);
			members.add(info);
		}
		return members;
	}
}

class MemberInfo implements Comparable<MemberInfo> {
	String name;
	String myGender;
	String requestGender;
	List<String> answers = new ArrayList<String>(10);
	int matchedNumber;

	public MemberInfo(String name, String myGender, String requestGender,
			List<String> answers) {
		this.name = name;
		this.myGender = myGender;
		this.requestGender = requestGender;
		this.answers = answers;
	}

	@Override
	public int compareTo(MemberInfo o) {
		if (matchedNumber == o.matchedNumber) {
			return 0;
		}

		return (matchedNumber > o.matchedNumber) ? -1 : 1;
	}
}
